package com.decent.util;

import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.encoders.Base64;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.security.Key;
import java.security.Security;
import java.util.Arrays;

/**
 * @author 鼎信橙劵
 */
public class AesUtil {
    /**
     * 请咨询橙劵索取密钥和偏移量
     */
    public static final String INTERFACE_KEY = "";
    /**
     * 编码方式
     */
    private static final String ENCODE_TYPE = "UTF-8";
    private static Key key;
    private static Cipher cipher;

    private static void init(byte[] keyBytes) {
        // 如果密钥不足16位，那么就补足.  这个if 中的内容很重要
        int base = 16;
        if (keyBytes.length % base != 0) {
            int groups = keyBytes.length / base + (keyBytes.length % base != 0 ? 1 : 0);
            byte[] temp = new byte[groups * base];
            Arrays.fill(temp, (byte) 0);
            System.arraycopy(keyBytes, 0, temp, 0, keyBytes.length);
            keyBytes = temp;
        }
        // 初始化
        Security.addProvider(new BouncyCastleProvider());
        // 转化成JAVA的密钥格式,算法名称
        key = new SecretKeySpec(keyBytes, "AES");
        try {
            // 初始化cipher,加解密算法/模式/填充方式
            cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 加密方法,String
     *
     * @param content 要加密的字符串
     * @param key     加密密钥
     * @return 密文
     */
    public static String encrypt(String content, String key, String iv) throws UnsupportedEncodingException {
        return new String(Base64.encode(encrypt(content.getBytes(ENCODE_TYPE), key.getBytes(ENCODE_TYPE), iv)), ENCODE_TYPE);
    }

    /**
     * 加密方法
     *
     * @param content  要加密的字符串
     * @param keyBytes 加密密钥
     * @return 密文(byte[])
     */
    private static byte[] encrypt(byte[] content, byte[] keyBytes, String iv) {
        byte[] encryptedText = null;
        init(keyBytes);
        try {
            cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(iv.getBytes(ENCODE_TYPE)));
            encryptedText = cipher.doFinal(content);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return encryptedText;
    }

    /**
     * 解密方法,String
     *
     * @param content 密文
     * @param key     加密密钥
     * @return 明文
     */
    public static String decrypt(String content, String key, String iv) throws UnsupportedEncodingException {
        return new String(decrypt(Base64.decode(content), key.getBytes(ENCODE_TYPE), iv), ENCODE_TYPE);
    }

    /**
     * 解密方法
     *
     * @param encryptedData 要解密的字符串
     * @param keyBytes      解密密钥
     * @param iv            偏移量
     * @return 原文
     */
    public static byte[] decrypt(byte[] encryptedData, byte[] keyBytes, String iv) {
        byte[] encryptedText = null;
        init(keyBytes);
        try {
            cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(iv.getBytes(ENCODE_TYPE)));
            encryptedText = cipher.doFinal(encryptedData);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return encryptedText;
    }
}